# 蒙特卡洛算法计算π值
import random
import math
import time

def calcPi(n):
    # 计算π值
    inside = 0
    for _ in range(n):
        x, y = random.random(), random.random()
        if x*x + y*y <= 1:
            inside += 1
    return 4 * inside / n

def testAccuracy():
    # 测试精度
    sizes = [100, 500, 1000, 5000, 10000]

    print("蒙特卡洛计算π值")
    print("=" * 70)
    print(f"{'点数':<8} {'π估算':<10} {'误差':<10} {'相对误差%':<12} {'时间':<10}")
    print("-" * 70)

    for n in sizes:
        start = time.time()
        pi = calcPi(n)
        t = time.time() - start

        err = abs(pi - math.pi)
        rel_err = (err / math.pi) * 100

        print(f"{n:<8} {pi:<10.6f} {err:<10.6f} {rel_err:<12.4f} {t:<10.6f}")

def multiTest(n, runs=5):
    # 多次测试
    print(f"\n多次测试 ({runs}次, 每次{n}点)")
    print("=" * 50)

    results = []
    for i in range(runs):
        pi = calcPi(n)
        results.append(pi)
        err = abs(pi - math.pi)
        print(f"第{i+1}次: π ≈ {pi:.6f}, 误差: {err:.6f}")

    avg = sum(results) / len(results)
    print(f"\n平均值: {avg:.8f}")
    print(f"真实值: {math.pi:.8f}")

def main():
    # 主函数
    print("蒙特卡洛π值计算")
    print("=" * 30)

    testAccuracy()
    multiTest(10000)

if __name__ == "__main__":
    main()